在Day22中當我們啟動ObserveService時會把MainActivity給終止掉,因此今天要做的內容事實上就是重啟MainActivity後能直接回到PreviewFragment的過程。
啟動時會在WelcomeFragment,由於已經是在Ptt內的狀態,可以直接跳過LoginFragment到後面。另外為了達到PreviewFramgnet點擊返回後能順利回到SearchArticleFragment的路線,我新加的Navigation Action會是WelcomeFragment到SearchArticleFragment的路線,接著再另外回到PreviewFragment。
<action
android:id="@+id/action_welcomeFragment_to_searchArticleFragment"
app:destination="@id/searchArticleFragment"
app:popUpTo="@id/welcomeFragment"
app:popUpToInclusive="true">
<argument
android:name="toPreview"
android:defaultValue="true"
app:argType="boolean"
app:nullable="false" />
</action>
可以看到我加入的是一個帶有argument的Action,這部份請參考Pass data between destinations。
<argument
android:name="toPreview"
android:defaultValue="false"
app:argType="boolean"
app:nullable="false" />
這是與welcomeFragment的argument對應的,但是在這邊的defaultValue設為false
,這是為了避免從LoginFragment進來時被這個argument影響到。
<argument
android:name="isInArticle"
android:defaultValue="false"
app:argType="boolean"
app:nullable="false" />
previewFragment中也加入一樣的Argument,這是因為從懸浮視窗回來時Ptt本來就已在文章裡面,不需要做原本PreviewFragment在Day16~Day17的內容中做的前置動作。
路線規劃好後就是處理程式碼的判斷了。
主要就是在點擊back時取消註冊updateRunnable並開啟新的MainActivity。
binding.back.setOnClickListener {
updateHandler.removeCallbacks(updateRunnable)
val intent = Intent(this, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(intent)
}
首先需要判斷目前ObserviceService是否正在啟動中。
在ObserviceService加入:
class ObserveService : Service() {
companion object {
public var isRunning = false
}
override fun onCreate() {
super.onCreate()
isRunning = true
// ...
}
override fun onDestroy() {
super.onDestroy()
isRunning = false
// ...
}
}
接著就能直接判斷了:
class WelcomeFragment : Fragment() {
//...
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
if (ObserveService.isRunning) {
requireActivity().stopService(
Intent(requireActivity(), ObserveService::class.java)
)
NavHostFragment.findNavController(this@WelcomeFragment)
.navigate(R.id.action_welcomeFragment_to_searchArticleFragment)
return
}
// ...
}
}
把ObserveService關閉並且使用剛剛新增的Action直接進到SearchArticleFragment,由於這個Action的toPreview argument預設值為true
,這邊就不需要做另外的操作了。
判斷若toPreview為true
的話直接進入PreviewFragment。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
arguments?.run {
if (SearchArticleFragmentArgs.fromBundle(this).toPreview) {
this.clear()
NavHostFragment.findNavController(this@SearchArticleFragment)
.navigate(
SearchArticleFragmentDirections
.actionSearchArticleFragmentToPreviewFragment(
true
)
)
return@onViewCreated
}
}
// ...
}
進入時記得要把isInArticle argument設為true
。
針對isInArticle做判斷即可。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
arguments?.run {
if (PreviewFragmentArgs.fromBundle(this).isInArticle) {
updateHandler.post(updateRunnable)
} else {
viewLifecycleOwner.lifecycleScope.launch(Dispatchers.IO) {
PttClient.getInstance().send("G")
delay(100L)
parseComments(PttClient.getInstance().getScreen())
updateHandler.postDelayed(updateRunnable, updateInterval)
}
}
}
}
先講結論就是可能明後天會針對這個Class做修改了,具體要改成什麼樣子我還在思考中。這邊會提到是因為從PreviewFragment回到SearchArticleFragment時,我需要保留先前的搜尋狀態,否則當進入ObserveService、把MainActivity退出後,原本存在SearchArticleFragment內的searchTitleSet、searchAuthorSet、currentBoard都會被清掉。為了保留這些狀態我是先把幾個變數放到PttClient這個singleton class中了。
public var currentBoard = ""
public val searchTitleSet = mutableSetOf<String>()
public val searchAuthorSet = mutableSetOf<String>()
接著在SearchArticleFragment開啟時將值重新放入。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// ...
binding.searchBoardInput.setText(PttClient.getInstance().currentBoard)
// ...
if ((PttClient.getInstance().searchAuthorSet.isNotEmpty()
|| PttClient.getInstance().searchTitleSet.isNotEmpty())
) {
(requireActivity() as MainActivity).showLoading("")
PttClient.getInstance().searchAuthorSet.forEach { addAuthorChip(it) }
PttClient.getInstance().searchTitleSet.forEach { addTitleChip(it) }
refreshSearch()
}
}
最後就是如一開始所說的,PttClient的修改(or 重做)已經是勢在必行了,畢竟目前使用上也不少彆扭的地方。
到目前為止基本上App的主要畫面和流程都已經出來了,接下來的幾天應該就是針對現有內容做修改/優化了。